import ajax, {type AjaxInstance, type AjaxRequestConfig, type AjaxResponse} from 'uni-ajax';
import {useClearStorageSync, useGetStorageSync, useToast} from "@/utils/tools";
import type {AxiosConfig, IResponse} from "@/typings/axios";
import {BASE_URL, LOCAL_URL} from "@/config";

const useRequest: AjaxInstance<AjaxRequestConfig> = ajax.create({
    baseURL: LOCAL_URL,
    timeout: 10000
});

useRequest.interceptors.request.use((request: AjaxRequestConfig) => {
        request.header['Authorization'] = 'Bearer ' + useGetStorageSync('token')
        return request
    }, error => {
        return Promise.reject(error)
    }
)

useRequest.interceptors.response.use((response: AjaxResponse) => {
        const code = response.data.code || 200;
        const msg = response.data.msg || response.data.message || '系统接口发生未知错误'
        if (code === 401 || code === 403) {
            useToast({message: '登录状态已过期'})
            useClearStorageSync()
            uni.reLaunch({url: "/pages/login/index"}).finally();
            return Promise.reject('登录状态已过期')
        } else if (code === 500) {
            useToast({message: msg})
            return Promise.reject(new Error(msg))
        } else if (code === 601) {
            useToast({message: msg})
            return Promise.reject(new Error(msg))
        } else if (code !== 200) {
            useToast({message: msg})
            return Promise.reject('error')
        } else {
            return Promise.resolve(response.data)
        }
    }, error => {
        let {message: errorMsg} = error;
        if (errorMsg == "Network Error") {
            errorMsg = "后端接口连接异常";
        } else if (errorMsg && errorMsg.includes("timeout")) {
            errorMsg = "系统接口请求超时";
        } else if (errorMsg && errorMsg.includes("Request failed with status code")) {
            errorMsg = "系统接口" + errorMsg.substring(errorMsg.length - 3) + "异常";
        }
        useToast({message: errorMsg || '系统接口发生未知错误'})
        return Promise.reject(error)
    }
)

class Request {
    post = <T = any>(url: AxiosConfig["url"], data: AxiosConfig["data"] = {}, _config: AjaxRequestConfig = {}) => {
        return useRequest.post(url, data, _config) as Promise<IResponse<T>>
    }
    put = <T = any>(url: AxiosConfig["url"], data: AxiosConfig["data"] = {}, _config: AjaxRequestConfig = {}) => {
        return useRequest.put(url, data, _config) as Promise<IResponse<T>>
    }
    get = <T = any>(url: AxiosConfig["url"], params: AxiosConfig["params"] = {}, _config: AjaxRequestConfig = {}) => {
        return useRequest.get(url, params, _config) as Promise<IResponse<T>>
    }

    delete = <T = any>(url: AxiosConfig["url"], params: AxiosConfig["params"] = {}, _config: AjaxRequestConfig = {}) => {
        return useRequest.delete(url, params, _config) as Promise<IResponse<T>>
    }
}

export default new Request()
